home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MOR55SRC.ZIP / MORIA / SOURCE / CREATURE.C < prev    next >
C/C++ Source or Header  |  1992-12-07  |  46KB  |  1,814 lines

  1. /* source/creature.c: handle monster movement and attacks
  2.  
  3.    Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  4.  
  5.    This software may be copied and distributed for educational, research, and
  6.    not for profit purposes provided that this copyright and statement are
  7.    included in all such copies. */
  8.  
  9. #ifdef __TURBOC__
  10. #include    <stdio.h>
  11. #include    <stdlib.h>
  12. #endif /* __TURBOC__ */
  13.  
  14. #include "config.h"
  15. #include "constant.h"
  16. #include "types.h"
  17. #include "externs.h"
  18.  
  19. #ifdef USG
  20. #ifndef ATARIST_MWC
  21. #include <string.h>
  22. #else
  23. char *strcat();
  24. char *strcpy();
  25. #endif
  26. #else
  27. #include <strings.h>
  28. #endif
  29.  
  30. #if defined(LINT_ARGS)
  31. static int movement_rate(int16);
  32. static int check_mon_lite(int, int);
  33. static void get_moves(int, int *);
  34. static void make_attack(int);
  35. static void make_move(int, int *, int32u *);
  36. static void mon_cast_spell(int, int *);
  37. static void mon_move(int, int32u *);
  38. #endif
  39.  
  40. #ifdef ATARIST_TC
  41. /* Include this to get prototypes for standard library functions.  */
  42. #include <stdlib.h>
  43. #endif
  44.  
  45.  
  46. /* Updates screen when monsters move about        -RAK-    */
  47. void update_mon(monptr)
  48. int monptr;
  49. {
  50.   register int flag;
  51.   register cave_type *c_ptr;
  52.   register monster_type *m_ptr;
  53.   register creature_type *r_ptr;
  54. #ifdef ATARIST_MWC
  55.   int32u holder;
  56. #endif
  57.  
  58.   m_ptr = &m_list[monptr];
  59.   flag = FALSE;
  60.   if ((m_ptr->cdis <= MAX_SIGHT) &&
  61.       !(py.flags.status & PY_BLIND) &&
  62.       (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)))
  63.     {
  64.       /* Wizard sight.         */
  65.       if (wizard)
  66.     flag = TRUE;
  67.       /* Normal sight.         */
  68.       else if (los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
  69.     {
  70.       c_ptr = &cave[m_ptr->fy][m_ptr->fx];
  71.       r_ptr = &c_list[m_ptr->mptr];
  72.       if (c_ptr->pl || c_ptr->tl ||
  73.           (find_flag && m_ptr->cdis < 2 && player_light))
  74.         {
  75. #ifdef ATARIST_MWC
  76.           holder = CM_INVISIBLE;
  77.           if ((holder & r_ptr->cmove) == 0)
  78. #else
  79.           if ((CM_INVISIBLE & r_ptr->cmove) == 0)
  80. #endif
  81.         flag = TRUE;
  82.           else if (py.flags.see_inv)
  83.         {
  84.           flag = TRUE;
  85. #ifdef ATARIST_MWC
  86.           c_recall[m_ptr->mptr].r_cmove |= holder;
  87. #else
  88.           c_recall[m_ptr->mptr].r_cmove |= CM_INVISIBLE;
  89. #endif
  90.         }
  91.         }
  92.       /* Infra vision.     */
  93.       else if ((py.flags.see_infra > 0) &&
  94.            (m_ptr->cdis <= py.flags.see_infra) &&
  95.            (CD_INFRA & r_ptr->cdefense))
  96.         {
  97.           flag = TRUE;
  98.           c_recall[m_ptr->mptr].r_cdefense |= CD_INFRA;
  99.         }
  100.     }
  101.     }
  102.   /* Light it up.     */
  103.   if (flag)
  104.     {
  105.       if (!m_ptr->ml)
  106.     {
  107.       disturb (1, 0);
  108.       m_ptr->ml = TRUE;
  109.       lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
  110.       screen_change = TRUE; /* notify inven_command */
  111.     }
  112.     }
  113.   /* Turn it off.     */
  114.   else if (m_ptr->ml)
  115.     {
  116.       m_ptr->ml = FALSE;
  117.       lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
  118.       screen_change = TRUE; /* notify inven_command */
  119.     }
  120. }
  121.  
  122.  
  123. /* Given speed,     returns number of moves this turn.    -RAK-    */
  124. /* NOTE: Player must always move at least once per iteration,      */
  125. /*     a slowed player is handled by moving monsters faster     */
  126. static int movement_rate(speed)
  127. register int16 speed;
  128. {
  129.   if (speed > 0)
  130.     {
  131.       if (py.flags.rest != 0)
  132.     return 1;
  133.       else
  134.     return speed;
  135.     }
  136.   else
  137.     {
  138.       /* speed must be negative here */
  139.       return ((turn % (2 - speed)) == 0);
  140.     }
  141. }
  142.  
  143.  
  144. /* Makes sure a new creature gets lit up.            -CJS- */
  145. static int check_mon_lite(y, x)
  146. int y, x;
  147. {
  148.   register int monptr;
  149.  
  150.   monptr = cave[y][x].cptr;
  151.   if (monptr <= 1)
  152.     return FALSE;
  153.   else
  154.     {
  155.       update_mon(monptr);
  156.       return m_list[monptr].ml;
  157.     }
  158. }
  159.  
  160.  
  161. /* Choose correct directions for monster movement    -RAK-    */
  162. static void get_moves(monptr, mm)
  163. int monptr;
  164. register int *mm;
  165. {
  166.   int y, ay, x, ax, move_val;
  167.  
  168.   y = m_list[monptr].fy - char_row;
  169.   x = m_list[monptr].fx - char_col;
  170.   if (y < 0)
  171.     {
  172.       move_val = 8;
  173.       ay = -y;
  174.     }
  175.   else
  176.     {
  177.       move_val = 0;
  178.       ay = y;
  179.     }
  180.   if (x > 0)
  181.     {
  182.       move_val += 4;
  183.       ax = x;
  184.     }
  185.   else
  186.     ax = -x;
  187.   /* this has the advantage of preventing the diamond maneuvre, also faster */
  188.   if (ay > (ax << 1))
  189.     move_val += 2;
  190.   else if (ax > (ay << 1))
  191.     move_val++;
  192.   switch(move_val)
  193.     {
  194.     case 0:
  195.       mm[0] = 9;
  196.       if (ay > ax)
  197.     {
  198.       mm[1] = 8;
  199.       mm[2] = 6;
  200.       mm[3] = 7;
  201.       mm[4] = 3;
  202.     }
  203.       else
  204.     {
  205.       mm[1] = 6;
  206.       mm[2] = 8;
  207.       mm[3] = 3;
  208.       mm[4] = 7;
  209.     }
  210.       break;
  211.     case 1: case 9:
  212.       mm[0] = 6;
  213.       if (y < 0)
  214.     {
  215.       mm[1] = 3;
  216.       mm[2] = 9;
  217.       mm[3] = 2;
  218.       mm[4] = 8;
  219.     }
  220.       else
  221.     {
  222.       mm[1] = 9;
  223.       mm[2] = 3;
  224.       mm[3] = 8;
  225.       mm[4] = 2;
  226.     }
  227.       break;
  228.     case 2: case 6:
  229.       mm[0] = 8;
  230.       if (x < 0)
  231.     {
  232.       mm[1] = 9;
  233.       mm[2] = 7;
  234.       mm[3] = 6;
  235.       mm[4] = 4;
  236.     }
  237.       else
  238.     {
  239.       mm[1] = 7;
  240.       mm[2] = 9;
  241.       mm[3] = 4;
  242.       mm[4] = 6;
  243.     }
  244.       break;
  245.     case 4:
  246.       mm[0] = 7;
  247.       if (ay > ax)
  248.     {
  249.       mm[1] = 8;
  250.       mm[2] = 4;
  251.       mm[3] = 9;
  252.       mm[4] = 1;
  253.     }
  254.       else
  255.     {
  256.       mm[1] = 4;
  257.       mm[2] = 8;
  258.       mm[3] = 1;
  259.       mm[4] = 9;
  260.     }
  261.       break;
  262.     case 5: case 13:
  263.       mm[0] = 4;
  264.       if (y < 0)
  265.     {
  266.       mm[1] = 1;
  267.       mm[2] = 7;
  268.       mm[3] = 2;
  269.       mm[4] = 8;
  270.     }
  271.       else
  272.     {
  273.       mm[1] = 7;
  274.       mm[2] = 1;
  275.       mm[3] = 8;
  276.       mm[4] = 2;
  277.     }
  278.       break;
  279.     case 8:
  280.       mm[0] = 3;
  281.       if (ay > ax)
  282.     {
  283.       mm[1] = 2;
  284.       mm[2] = 6;
  285.       mm[3] = 1;
  286.       mm[4] = 9;
  287.     }
  288.       else
  289.     {
  290.       mm[1] = 6;
  291.       mm[2] = 2;
  292.       mm[3] = 9;
  293.       mm[4] = 1;
  294.     }
  295.       break;
  296.     case 10: case 14:
  297.       mm[0] = 2;
  298.       if (x < 0)
  299.     {
  300.       mm[1] = 3;
  301.       mm[2] = 1;
  302.       mm[3] = 6;
  303.       mm[4] = 4;
  304.     }
  305.       else
  306.     {
  307.       mm[1] = 1;
  308.       mm[2] = 3;
  309.       mm[3] = 4;
  310.       mm[4] = 6;
  311.     }
  312.       break;
  313.     case 12:
  314.       mm[0] = 1;
  315.       if (ay > ax)
  316.     {
  317.       mm[1] = 2;
  318.       mm[2] = 4;
  319.       mm[3] = 3;
  320.       mm[4] = 7;
  321.     }
  322.       else
  323.     {
  324.       mm[1] = 4;
  325.       mm[2] = 2;
  326.       mm[3] = 7;
  327.       mm[4] = 3;
  328.     }
  329.       break;
  330.     }
  331. }
  332.  
  333.  
  334. /* Make an attack on the player (chuckle.)        -RAK-    */
  335. static void make_attack(monptr)
  336. int monptr;
  337. {
  338.   int attype, adesc, adice, asides;
  339.   int i, j, damage, flag, attackn, notice, visible;
  340.   int32 gold;
  341.   int8u *attstr;
  342.   vtype cdesc, tmp_str, ddesc;
  343.   register creature_type *r_ptr;
  344.   monster_type *m_ptr;
  345.   register struct misc *p_ptr;
  346.   register struct flags *f_ptr;
  347.   register inven_type *i_ptr;
  348. #ifdef ATARIST_MWC
  349.   int32u holder;
  350. #endif
  351.  
  352.   if (death)  /* don't beat a dead body! */
  353.     return;
  354.  
  355.   m_ptr = &m_list[monptr];
  356.   r_ptr = &c_list[m_ptr->mptr];
  357.   if (!m_ptr->ml)
  358.     (void) strcpy(cdesc, "It ");
  359.   else
  360.     (void) sprintf(cdesc, "The %s ", r_ptr->name);
  361.   /* For "DIED_FROM" string       */
  362. #ifdef ATARIST_MWC
  363.   holder = CM_WIN;
  364.   if (holder & r_ptr->cmove)
  365. #else
  366.   if (CM_WIN & r_ptr->cmove)
  367. #endif
  368.     (void) sprintf(ddesc, "The %s", r_ptr->name);
  369.   else if (is_a_vowel (r_ptr->name[0]))
  370.     (void) sprintf(ddesc, "an %s", r_ptr->name);
  371.   else
  372.     (void) sprintf (ddesc, "a %s", r_ptr->name);
  373.   /* End DIED_FROM           */
  374.  
  375.   attackn = 0;
  376.   attstr = r_ptr->damage;
  377.   while ((*attstr != 0) && !death)
  378.     {
  379.       attype = monster_attacks[*attstr].attack_type;
  380.       adesc = monster_attacks[*attstr].attack_desc;
  381.       adice = monster_attacks[*attstr].attack_dice;
  382.       asides = monster_attacks[*attstr].attack_sides;
  383.       attstr++;
  384.       flag = FALSE;
  385.       if ((py.flags.protevil > 0) && (r_ptr->cdefense & CD_EVIL) &&
  386.       ((py.misc.lev + 1) > r_ptr->level))
  387.     {
  388.       if (m_ptr->ml)
  389.         c_recall[m_ptr->mptr].r_cdefense |= CD_EVIL;
  390.       attype = 99;
  391.       adesc = 99;
  392.     }
  393.       p_ptr = &py.misc;
  394.       switch(attype)
  395.     {
  396.     case 1:          /*Normal attack  */
  397.       if (test_hit(60, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  398.                CLA_MISC_HIT))
  399.         flag = TRUE;
  400.       break;
  401.     case 2:          /*Lose Strength*/
  402.       if (test_hit(-3, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  403.                CLA_MISC_HIT))
  404.         flag = TRUE;
  405.       break;
  406.     case 3:          /*Confusion attack*/
  407.       if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  408.                CLA_MISC_HIT))
  409.         flag = TRUE;
  410.       break;
  411.     case 4:          /*Fear attack    */
  412.       if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  413.                CLA_MISC_HIT))
  414.         flag = TRUE;
  415.       break;
  416.     case 5:          /*Fire attack    */
  417.       if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  418.                CLA_MISC_HIT))
  419.         flag = TRUE;
  420.       break;
  421.     case 6:          /*Acid attack    */
  422.       if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  423.                CLA_MISC_HIT))
  424.         flag = TRUE;
  425.       break;
  426.     case 7:          /*Cold attack    */
  427.       if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  428.                CLA_MISC_HIT))
  429.         flag = TRUE;
  430.       break;
  431.     case 8:          /*Lightning attack*/
  432.       if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  433.                CLA_MISC_HIT))
  434.         flag = TRUE;
  435.       break;
  436.     case 9:          /*Corrosion attack*/
  437.       if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  438.                CLA_MISC_HIT))
  439.         flag = TRUE;
  440.       break;
  441.     case 10:      /*Blindness attack*/
  442.       if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  443.                CLA_MISC_HIT))
  444.         flag = TRUE;
  445.       break;
  446.     case 11:      /*Paralysis attack*/
  447.       if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  448.                CLA_MISC_HIT))
  449.         flag = TRUE;
  450.       break;
  451.     case 12:      /*Steal Money    */
  452.       if ((test_hit(5, (int)r_ptr->level, 0, (int)py.misc.lev,
  453.             CLA_MISC_HIT))
  454.           && (py.misc.au > 0))
  455.         flag = TRUE;
  456.       break;
  457.     case 13:      /*Steal Object   */
  458.       if ((test_hit(2, (int)r_ptr->level, 0, (int)py.misc.lev,
  459.             CLA_MISC_HIT))
  460.           && (inven_ctr > 0))
  461.         flag = TRUE;
  462.       break;
  463.     case 14:      /*Poison           */
  464.       if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  465.                CLA_MISC_HIT))
  466.         flag = TRUE;
  467.       break;
  468.     case 15:      /*Lose dexterity*/
  469.       if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  470.                CLA_MISC_HIT))
  471.         flag = TRUE;
  472.       break;
  473.     case 16:      /*Lose constitution*/
  474.       if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  475.                CLA_MISC_HIT))
  476.         flag = TRUE;
  477.       break;
  478.     case 17:      /*Lose intelligence*/
  479.       if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  480.                CLA_MISC_HIT))
  481.         flag = TRUE;
  482.       break;
  483.     case 18:      /*Lose wisdom*/
  484.       if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  485.                CLA_MISC_HIT))
  486.         flag = TRUE;
  487.       break;
  488.     case 19:      /*Lose experience*/
  489.       if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  490.                CLA_MISC_HIT))
  491.         flag = TRUE;
  492.       break;
  493.     case 20:      /*Aggravate monsters*/
  494.       flag = TRUE;
  495.       break;
  496.     case 21:      /*Disenchant      */
  497.       if (test_hit(20, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  498.                CLA_MISC_HIT))
  499.         flag = TRUE;
  500.       break;
  501.     case 22:      /*Eat food      */
  502.       if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  503.                CLA_MISC_HIT))
  504.         flag = TRUE;
  505.       break;
  506.     case 23:      /*Eat light      */
  507.       if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  508.                CLA_MISC_HIT))
  509.         flag = TRUE;
  510.       break;
  511.     case 24:      /*Eat charges      */
  512.       if ((test_hit(15, (int)r_ptr->level, 0, p_ptr->pac+p_ptr->ptoac,
  513.             CLA_MISC_HIT)) &&
  514.           (inven_ctr > 0))    /* check to make sure an object exists */
  515.         flag = TRUE;
  516.       break;
  517.     case 99:
  518.       flag = TRUE;
  519.       break;
  520.     default:
  521.       break;
  522.     }
  523.       if (flag)
  524.     {
  525.       /* can not strcat to cdesc because the creature may have
  526.          multiple attacks */
  527.       disturb (1, 0);
  528.       (void) strcpy(tmp_str, cdesc);
  529.       switch(adesc)
  530.         {
  531.         case 1: msg_print(strcat(tmp_str, "hits you.")); break;
  532.         case 2: msg_print(strcat(tmp_str, "bites you.")); break;
  533.         case 3: msg_print(strcat(tmp_str, "claws you.")); break;
  534.         case 4: msg_print(strcat(tmp_str, "stings you.")); break;
  535.         case 5: msg_print(strcat(tmp_str, "touches you.")); break;
  536. #if 0
  537.         case 6: msg_print(strcat(tmp_str, "kicks you.")); break;
  538. #endif
  539.         case 7: msg_print(strcat(tmp_str, "gazes at you.")); break;
  540.         case 8: msg_print(strcat(tmp_str, "breathes on you.")); break;
  541.         case 9: msg_print(strcat(tmp_str, "spits on you.")); break;
  542.         case 10: msg_print(strcat(tmp_str,"makes a horrible wail."));break;
  543. #if 0
  544.         case 11: msg_print(strcat(tmp_str, "embraces you.")); break;
  545. #endif
  546.         case 12: msg_print(strcat(tmp_str, "crawls on you.")); break;
  547.         case 13:
  548.           msg_print(strcat(tmp_str, "releases a cloud of spores.")); break;
  549.         case 14: msg_print(strcat(tmp_str, "begs you for money.")); break;
  550.         case 15: msg_print("You've been slimed!"); break;
  551.         case 16: msg_print(strcat(tmp_str, "crushes you.")); break;
  552.         case 17: msg_print(strcat(tmp_str, "tramples you.")); break;
  553.         case 18: msg_print(strcat(tmp_str, "drools on you.")); break;
  554.         case 19:
  555.           switch(randint(9))
  556.         {
  557.         case 1: msg_print(strcat(tmp_str, "insults you!")); break;
  558.         case 2:
  559.           msg_print(strcat(tmp_str, "insults your mother!")); break;
  560.         case 3:
  561.           msg_print(strcat(tmp_str, "gives you the finger!")); break;
  562.         case 4: msg_print(strcat(tmp_str, "humiliates you!")); break;
  563.         case 5: msg_print(strcat(tmp_str, "wets on your leg!")); break;
  564.         case 6: msg_print(strcat(tmp_str, "defiles you!")); break;
  565.         case 7: msg_print(strcat(tmp_str, "dances around you!"));break;
  566.         case 8:
  567.           msg_print(strcat(tmp_str, "makes obscene gestures!")); break;
  568.         case 9: msg_print(strcat(tmp_str, "moons you!!!")); break;
  569.         }
  570.           break;
  571.         case 99: msg_print(strcat(tmp_str, "is repelled.")); break;
  572.         default: break;
  573.         }
  574.  
  575.       notice = TRUE;
  576.       /* always fail to notice attack if creature invisible, set notice
  577.          and visible here since creature may be visible when attacking
  578.          and then teleport afterwards (becoming effectively invisible) */
  579.       if (!m_ptr->ml)
  580.         {
  581.           visible = FALSE;
  582.           notice = FALSE;
  583.         }
  584.       else
  585.         visible = TRUE;
  586.  
  587.       damage = damroll (adice, asides);
  588.       switch(attype)
  589.         {
  590.         case 1:    /*Normal attack    */
  591.           /* round half-way case down */
  592.           damage -= ((p_ptr->pac+p_ptr->ptoac) * damage) / 200;
  593.           take_hit(damage, ddesc);
  594.           break;
  595.         case 2:    /*Lose Strength*/
  596.           take_hit(damage, ddesc);
  597.           if (py.flags.sustain_str)
  598.         msg_print("You feel weaker for a moment, but it passes.");
  599.           else if (randint(2) == 1)
  600.         {
  601.           msg_print("You feel weaker.");
  602.           (void) dec_stat (A_STR);
  603.         }
  604.           else
  605.         notice = FALSE;
  606.           break;
  607.         case 3:    /*Confusion attack*/
  608.           f_ptr = &py.flags;
  609.           take_hit(damage, ddesc);
  610.           if (randint(2) == 1)
  611.         {
  612.           if (f_ptr->confused < 1)
  613.             {
  614.               msg_print("You feel confused.");
  615.               f_ptr->confused += randint((int)r_ptr->level);
  616.             }
  617.           else
  618.             notice = FALSE;
  619.           f_ptr->confused += 3;
  620.         }
  621.           else
  622.         notice = FALSE;
  623.           break;
  624.         case 4:    /*Fear attack    */
  625.           f_ptr = &py.flags;
  626.           take_hit(damage, ddesc);
  627.           if (player_saves())
  628.         msg_print("You resist the effects!");
  629.           else if (f_ptr->afraid < 1)
  630.         {
  631.           msg_print("You are suddenly afraid!");
  632.           f_ptr->afraid += 3 + randint((int)r_ptr->level);
  633.         }
  634.           else
  635.         {
  636.           f_ptr->afraid += 3;
  637.           notice = FALSE;
  638.         }
  639.           break;
  640.         case 5:    /*Fire attack    */
  641.           msg_print("You are enveloped in flames!");
  642.           fire_dam(damage, ddesc);
  643.           break;
  644.         case 6:    /*Acid attack    */
  645.           msg_print("You are covered in acid!");
  646.           acid_dam(damage, ddesc);
  647.           break;
  648.         case 7:    /*Cold attack    */
  649.           msg_print("You are covered with frost!");
  650.           cold_dam(damage, ddesc);
  651.           break;
  652.         case 8:    /*Lightning attack*/
  653.           msg_print("Lightning strikes you!");
  654.           light_dam(damage, ddesc);
  655.           break;
  656.         case 9:    /*Corrosion attack*/
  657.           msg_print("A stinging red gas swirls about you.");
  658.           corrode_gas(ddesc);
  659.           take_hit(damage, ddesc);
  660.           break;
  661.         case 10:    /*Blindness attack*/
  662.           f_ptr = &py.flags;
  663.           take_hit(damage, ddesc);
  664.           if (f_ptr->blind < 1)
  665.         {
  666.           f_ptr->blind += 10 + randint((int)r_ptr->level);
  667.           msg_print("Your eyes begin to sting.");
  668.         }
  669.           else
  670.         {
  671.           f_ptr->blind += 5;
  672.           notice = FALSE;
  673.         }
  674.           break;
  675.         case 11:    /*Paralysis attack*/
  676.           f_ptr = &py.flags;
  677.           take_hit(damage, ddesc);
  678.           if (player_saves())
  679.         msg_print("You resist the effects!");
  680.           else if (f_ptr->paralysis < 1)
  681.         {
  682.           if (f_ptr->free_act)
  683.             msg_print("You are unaffected.");
  684.           else
  685.             {
  686.               f_ptr->paralysis = randint((int)r_ptr->level) + 3;
  687.               msg_print("You are paralyzed.");
  688.             }
  689.         }
  690.           else
  691.         notice = FALSE;
  692.           break;
  693.         case 12:    /*Steal Money      */
  694.           if ((py.flags.paralysis < 1) &&
  695.           (randint(124) < py.stats.use_stat[A_DEX]))
  696.         msg_print("You quickly protect your money pouch!");
  697.           else
  698.         {
  699.           gold = (p_ptr->au/10) + randint(25);
  700.           if (gold > p_ptr->au)
  701.             p_ptr->au = 0;
  702.           else
  703.             p_ptr->au -= gold;
  704.           msg_print("Your purse feels lighter.");
  705.           prt_gold();
  706.         }
  707.           if (randint(2) == 1)
  708.         {
  709.           msg_print("There is a puff of smoke!");
  710.           teleport_away(monptr, MAX_SIGHT);
  711.         }
  712.           break;
  713.         case 13:    /*Steal Object     */
  714.           if ((py.flags.paralysis < 1) &&
  715.           (randint(124) < py.stats.use_stat[A_DEX]))
  716.         msg_print("You grab hold of your backpack!");
  717.           else
  718.         {
  719.           i = randint(inven_ctr) - 1;
  720.           inven_destroy(i);
  721.           msg_print("Your backpack feels lighter.");
  722.         }
  723.           if (randint(2) == 1)
  724.         {
  725.           msg_print("There is a puff of smoke!");
  726.           teleport_away(monptr, MAX_SIGHT);
  727.         }
  728.           break;
  729.         case 14:    /*Poison     */
  730.           f_ptr = &py.flags;
  731.           take_hit(damage, ddesc);
  732.           msg_print("You feel very sick.");
  733.           f_ptr->poisoned += randint((int)r_ptr->level)+5;
  734.           break;
  735.         case 15:    /*Lose dexterity */
  736.           f_ptr = &py.flags;
  737.           take_hit(damage, ddesc);
  738.           if (f_ptr->sustain_dex)
  739.         msg_print("You feel clumsy for a moment, but it passes.");
  740.           else
  741.         {
  742.           msg_print("You feel more clumsy.");
  743.           (void) dec_stat (A_DEX);
  744.         }
  745.           break;
  746.         case 16:    /*Lose constitution */
  747.           f_ptr = &py.flags;
  748.           take_hit(damage, ddesc);
  749.           if (f_ptr->sustain_con)
  750.         msg_print("Your body resists the effects of the disease.");
  751.           else
  752.         {
  753.           msg_print("Your health is damaged!");
  754.           (void) dec_stat (A_CON);
  755.         }
  756.           break;
  757.         case 17:    /*Lose intelligence */
  758.           f_ptr = &py.flags;
  759.           take_hit(damage, ddesc);
  760.           msg_print("You have trouble thinking clearly.");
  761.           if (f_ptr->sustain_int)
  762.         msg_print("But your mind quickly clears.");
  763.           else
  764.         (void) dec_stat (A_INT);
  765.           break;
  766.         case 18:    /*Lose wisdom       */
  767.           f_ptr = &py.flags;
  768.           take_hit(damage, ddesc);
  769.           if (f_ptr->sustain_wis)
  770.         msg_print("Your wisdom is sustained.");
  771.           else
  772.         {
  773.           msg_print("Your wisdom is drained.");
  774.           (void) dec_stat (A_WIS);
  775.         }
  776.           break;
  777.         case 19:    /*Lose experience  */
  778.           msg_print("You feel your life draining away!");
  779.           lose_exp(damage + (py.misc.exp / 100)*MON_DRAIN_LIFE);
  780.           break;
  781.         case 20:    /*Aggravate monster*/
  782.           (void) aggravate_monster(20);
  783.           break;
  784.         case 21:    /*Disenchant       */
  785.           flag = FALSE;
  786.           switch(randint(7))
  787.         {
  788.         case 1: i = INVEN_WIELD; break;
  789.         case 2: i = INVEN_BODY;     break;
  790.         case 3: i = INVEN_ARM;     break;
  791.         case 4: i = INVEN_OUTER; break;
  792.         case 5: i = INVEN_HANDS; break;
  793.         case 6: i = INVEN_HEAD;     break;
  794.         case 7: i = INVEN_FEET;     break;
  795.         }
  796.           i_ptr = &inventory[i];
  797.           if (i_ptr->tohit > 0)
  798.         {
  799.           i_ptr->tohit -= randint(2);
  800.           /* don't send it below zero */
  801.           if (i_ptr->tohit < 0)
  802.             i_ptr->tohit = 0;
  803.           flag = TRUE;
  804.         }
  805.           if (i_ptr->todam > 0)
  806.         {
  807.           i_ptr->todam -= randint(2);
  808.           /* don't send it below zero */
  809.           if (i_ptr->todam < 0)
  810.             i_ptr->todam = 0;
  811.           flag = TRUE;
  812.         }
  813.           if (i_ptr->toac > 0)
  814.         {
  815.           i_ptr->toac  -= randint(2);
  816.           /* don't send it below zero */
  817.           if (i_ptr->toac < 0)
  818.             i_ptr->toac = 0;
  819.           flag = TRUE;
  820.         }
  821.           if (flag)
  822.         {
  823.           msg_print("There is a static feeling in the air.");
  824.           calc_bonuses ();
  825.         }
  826.           else
  827.         notice = FALSE;
  828.           break;
  829.         case 22:    /*Eat food       */
  830.           if (find_range(TV_FOOD, TV_NEVER, &i, &j))
  831.         {
  832.           inven_destroy(i);
  833.           msg_print ("It got at your rations!");
  834.         }
  835.           else
  836.         notice = FALSE;
  837.           break;
  838.         case 23:    /*Eat light       */
  839.           i_ptr = &inventory[INVEN_LIGHT];
  840.           if (i_ptr->p1 > 0)
  841.         {
  842.           i_ptr->p1 -= (250 + randint(250));
  843.           if (i_ptr->p1 < 1)  i_ptr->p1 = 1;
  844.           if (py.flags.blind < 1)
  845.             msg_print("Your light dims.");
  846.           else
  847.             notice = FALSE;
  848.         }
  849.           else
  850.         notice = FALSE;
  851.           break;
  852.         case 24:    /*Eat charges      */
  853.           i = randint(inven_ctr) - 1;
  854.           j = r_ptr->level;
  855.           i_ptr = &inventory[i];
  856.           if (((i_ptr->tval == TV_STAFF) || (i_ptr->tval == TV_WAND))
  857.           && (i_ptr->p1 > 0))
  858.         {
  859.           m_ptr->hp += j*i_ptr->p1;
  860.           i_ptr->p1 = 0;
  861.           if (! known2_p (i_ptr))
  862.             add_inscribe (i_ptr, ID_EMPTY);
  863.           msg_print("Energy drains from your pack!");
  864.         }
  865.           else
  866.         notice = FALSE;
  867.           break;
  868.         case 99:
  869.           notice = FALSE;
  870.           break;
  871.         default:
  872.           notice = FALSE;
  873.           break;
  874.         }
  875.  
  876.       /* Moved here from mon_move, so that monster only confused if it
  877.          actually hits.  A monster that has been repelled has not hit
  878.          the player, so it should not be confused.  */
  879.       if (py.flags.confuse_monster && adesc != 99)
  880.         {
  881.           msg_print("Your hands stop glowing.");
  882.           py.flags.confuse_monster = FALSE;
  883.           if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
  884.           (CD_NO_SLEEP & r_ptr->cdefense))
  885.         (void) sprintf(tmp_str, "%sis unaffected.", cdesc);
  886.           else
  887.         {
  888.           (void) sprintf(tmp_str, "%sappears confused.", cdesc);
  889.           m_ptr->confused = TRUE;
  890.         }
  891.           msg_print(tmp_str);
  892.           if (visible && !death && randint(4) == 1)
  893.         c_recall[m_ptr->mptr].r_cdefense |= r_ptr->cdefense &
  894.           CD_NO_SLEEP;
  895.         }
  896.  
  897.       /* increase number of attacks if notice true, or if visible and had
  898.          previously noticed the attack (in which case all this does is
  899.          help player learn damage), note that in the second case do
  900.          not increase attacks if creature repelled (no damage done) */
  901.       if ((notice ||
  902.            (visible && c_recall[m_ptr->mptr].r_attacks[attackn] != 0 &&
  903.         attype != 99))
  904.           && c_recall[m_ptr->mptr].r_attacks[attackn] < MAX_UCHAR)
  905.         c_recall[m_ptr->mptr].r_attacks[attackn]++;
  906.       if (death && c_recall[m_ptr->mptr].r_deaths < MAX_SHORT)
  907.         c_recall[m_ptr->mptr].r_deaths++;
  908.     }
  909.       else
  910.     {
  911.       if ((adesc >= 1 && adesc <= 3) || (adesc == 6))
  912.         {
  913.           disturb (1, 0);
  914.           (void) strcpy(tmp_str, cdesc);
  915.           msg_print(strcat(tmp_str, "misses you."));
  916.         }
  917.     }
  918.       if (attackn < MAX_MON_NATTACK-1)
  919.     attackn++;
  920.       else
  921.     break;
  922.     }
  923. }
  924.  
  925.  
  926. /* Make the move if possible, five choices        -RAK-    */
  927. static void make_move(monptr, mm, rcmove)
  928. int monptr;
  929. int *mm;
  930. int32u *rcmove;
  931. {
  932.   int i, newy, newx, do_turn, do_move, stuck_door;
  933.   int32u movebits;
  934.   register cave_type *c_ptr;
  935.   register monster_type *m_ptr;
  936.   register inven_type *t_ptr;
  937. #ifdef ATARIST_MWC
  938.   int32u holder;
  939. #endif
  940.  
  941.   i = 0;
  942.   do_turn = FALSE;
  943.   do_move = FALSE;
  944.   m_ptr = &m_list[monptr];
  945.   movebits = c_list[m_ptr->mptr].cmove;
  946.   do
  947.     {
  948.       /* Get new position        */
  949.       newy = m_ptr->fy;
  950.       newx = m_ptr->fx;
  951.       (void) mmove(mm[i], &newy, &newx);
  952.       c_ptr = &cave[newy][newx];
  953.       if (c_ptr->fval != BOUNDARY_WALL)
  954.     {
  955.       /* Floor is open?           */
  956.       if (c_ptr->fval <= MAX_OPEN_SPACE)
  957.         do_move = TRUE;
  958.       /* Creature moves through walls? */
  959. #ifdef ATARIST_MWC
  960.       else if (movebits & (holder = CM_PHASE))
  961. #else
  962.       else if (movebits & CM_PHASE)
  963. #endif
  964.         {
  965.           do_move = TRUE;
  966. #ifdef ATARIST_MWC
  967.           *rcmove |= holder;
  968. #else
  969.           *rcmove |= CM_PHASE;
  970. #endif
  971.         }
  972.       /* Creature can open doors?       */
  973.       else if (c_ptr->tptr != 0)
  974.         {
  975.           t_ptr = &t_list[c_ptr->tptr];
  976. #ifdef ATARIST_MWC
  977.           if (movebits & (holder = CM_OPEN_DOOR))
  978. #else
  979.           if (movebits & CM_OPEN_DOOR)
  980. #endif
  981.         {     /* Creature can open doors.             */
  982.           stuck_door = FALSE;
  983.           if (t_ptr->tval == TV_CLOSED_DOOR)
  984.             {
  985.               do_turn = TRUE;
  986.               if (t_ptr->p1 == 0)        /* Closed doors     */
  987.             do_move = TRUE;
  988.               else if (t_ptr->p1 > 0)           /* Locked doors    */
  989.             {
  990.               if (randint((m_ptr->hp+1)*(50+t_ptr->p1)) <
  991.                   40*(m_ptr->hp-10-t_ptr->p1))
  992.                 t_ptr->p1 = 0;
  993.             }
  994.               else if (t_ptr->p1 < 0)           /* Stuck doors    */
  995.             {
  996.               if (randint((m_ptr->hp+1)*(50-t_ptr->p1)) <
  997.                   40*(m_ptr->hp-10+t_ptr->p1))
  998.                 {
  999.                   msg_print("You hear a door burst open!");
  1000.                   disturb (1, 0);
  1001.                   stuck_door = TRUE;
  1002.                   do_move = TRUE;
  1003.                 }
  1004.             }
  1005.             }
  1006.           else if (t_ptr->tval == TV_SECRET_DOOR)
  1007.             {
  1008.               do_turn = TRUE;
  1009.               do_move = TRUE;
  1010.             }
  1011.           if (do_move)
  1012.             {
  1013.               invcopy(t_ptr, OBJ_OPEN_DOOR);
  1014.               if (stuck_door) /* 50% chance of breaking door */
  1015.             t_ptr->p1 = 1 - randint(2);
  1016.               c_ptr->fval = CORR_FLOOR;
  1017.               lite_spot(newy, newx);
  1018. #ifdef ATARIST_MWC
  1019.               *rcmove |= holder;
  1020. #else
  1021.               *rcmove |= CM_OPEN_DOOR;
  1022. #endif
  1023.               do_move = FALSE;
  1024.             }
  1025.         }
  1026.           else
  1027.         {     /* Creature can not open doors, must bash them   */
  1028.           if (t_ptr->tval == TV_CLOSED_DOOR)
  1029.             {
  1030.               do_turn = TRUE;
  1031.               if (randint((m_ptr->hp+1)*(80+abs(t_ptr->p1))) <
  1032.               40*(m_ptr->hp-20-abs(t_ptr->p1)))
  1033.             {
  1034.               invcopy(t_ptr, OBJ_OPEN_DOOR);
  1035.               /* 50% chance of breaking door */
  1036.               t_ptr->p1 = 1 - randint(2);
  1037.               c_ptr->fval = CORR_FLOOR;
  1038.               lite_spot(newy, newx);
  1039.               msg_print ("You hear a door burst open!");
  1040.               disturb (1, 0);
  1041.             }
  1042.             }
  1043.         }
  1044.         }
  1045.       /* Glyph of warding present?       */
  1046.       if (do_move && (c_ptr->tptr != 0) &&
  1047.           (t_list[c_ptr->tptr].tval == TV_VIS_TRAP) &&
  1048.           (t_list[c_ptr->tptr].subval == 99))
  1049.         {
  1050.           if (randint(OBJ_RUNE_PROT) < c_list[m_ptr->mptr].level)
  1051.         {
  1052.           if ((newy==char_row) && (newx==char_col))
  1053.             msg_print("The rune of protection is broken!");
  1054.           (void) delete_object(newy, newx);
  1055.         }
  1056.           else
  1057.         {
  1058.           do_move = FALSE;
  1059.           /* If the creature moves only to attack, */
  1060.           /* don't let it move if the glyph prevents */
  1061.           /* it from attacking */
  1062.           if (movebits & CM_ATTACK_ONLY)
  1063.             do_turn = TRUE;
  1064.         }
  1065.         }
  1066.       /* Creature has attempted to move on player?       */
  1067.       if (do_move)
  1068.         if (c_ptr->cptr == 1)
  1069.           {
  1070.         /* if the monster is not lit, must call update_mon, it may
  1071.            be faster than character, and hence could have just
  1072.            moved next to character this same turn */
  1073.         if (!m_ptr->ml)
  1074.           update_mon(monptr);
  1075.         make_attack(monptr);
  1076.         do_move = FALSE;
  1077.         do_turn = TRUE;
  1078.           }
  1079.       /* Creature is attempting to move on other creature?       */
  1080.         else if ((c_ptr->cptr > 1) &&
  1081.              ((newy != m_ptr->fy) ||
  1082.               (newx != m_ptr->fx)))
  1083.           {
  1084.         /* Creature eats other creatures?     */
  1085. #ifdef ATARIST_MWC
  1086.         if ((movebits & (holder = CM_EATS_OTHER)) &&
  1087. #else
  1088.         if ((movebits & CM_EATS_OTHER) &&
  1089. #endif
  1090.             (c_list[m_ptr->mptr].mexp >=
  1091.              c_list[m_list[c_ptr->cptr].mptr].mexp))
  1092.           {
  1093.             if (m_list[c_ptr->cptr].ml)
  1094. #ifdef ATARIST_MWC
  1095.               *rcmove |= holder;
  1096. #else
  1097.               *rcmove |= CM_EATS_OTHER;
  1098. #endif
  1099.             /* It ate an already processed monster. Handle normally. */
  1100.             if (monptr < c_ptr->cptr)
  1101.               delete_monster((int) c_ptr->cptr);
  1102.             /* If it eats this monster, an already processed monster
  1103.                will take its place, causing all kinds of havoc.  Delay
  1104.                the kill a bit. */
  1105.             else
  1106.               fix1_delete_monster((int) c_ptr->cptr);
  1107.           }
  1108.         else
  1109.           do_move = FALSE;
  1110.           }
  1111.       /* Creature has been allowed move.     */
  1112.       if (do_move)
  1113.         {
  1114.           /* Pick up or eat an object           */
  1115. #ifdef ATARIST_MWC
  1116.           if (movebits & (holder = CM_PICKS_UP))
  1117. #else
  1118.           if (movebits & CM_PICKS_UP)
  1119. #endif
  1120.         {
  1121.           c_ptr = &cave[newy][newx];
  1122.  
  1123.           if ((c_ptr->tptr != 0)
  1124.               && (t_list[c_ptr->tptr].tval <= TV_MAX_OBJECT))
  1125.             {
  1126. #ifdef ATARIST_MWC
  1127.               *rcmove |= holder;
  1128. #else
  1129.               *rcmove |= CM_PICKS_UP;
  1130. #endif
  1131.               (void) delete_object(newy, newx);
  1132.             }
  1133.         }
  1134.           /* Move creature record               */
  1135.           move_rec((int)m_ptr->fy, (int)m_ptr->fx, newy, newx);
  1136.           if (m_ptr->ml)
  1137.         {
  1138.           m_ptr->ml = FALSE;
  1139.           lite_spot ((int)m_ptr->fy, (int)m_ptr->fx);
  1140.         }
  1141.           m_ptr->fy = newy;
  1142.           m_ptr->fx = newx;
  1143.           m_ptr->cdis = distance (char_row, char_col, newy, newx);
  1144.           do_turn = TRUE;
  1145.         }
  1146.     }
  1147.       i++;
  1148.       /* Up to 5 attempts at moving,   give up.      */
  1149.     }
  1150.   while ((!do_turn) && (i < 5));
  1151. }
  1152.  
  1153.  
  1154. /* Creatures can cast spells too.  (Dragon Breath)    -RAK-    */
  1155. /* cast_spell = true if creature changes position    */
  1156. /* took_turn  = true if creature casts a spell        */
  1157. static void mon_cast_spell(monptr, took_turn)
  1158. int monptr;
  1159. int *took_turn;
  1160. {
  1161.   int32u i;
  1162.   int y, x, chance, thrown_spell, r1;
  1163.   register int k;
  1164.   int spell_choice[30];
  1165.   vtype cdesc, outval, ddesc;
  1166.   register monster_type *m_ptr;
  1167.   register creature_type *r_ptr;
  1168. #ifdef ATARIST_MWC
  1169.   int32u holder;
  1170. #endif
  1171.  
  1172.   if (death)
  1173.     return;
  1174.  
  1175.   m_ptr = &m_list[monptr];
  1176.   r_ptr = &c_list[m_ptr->mptr];
  1177.   chance = (int)(r_ptr->spells & CS_FREQ);
  1178.   /* 1 in x chance of casting spell           */
  1179.   if (randint(chance) != 1)
  1180.     *took_turn    = FALSE;
  1181.   /* Must be within certain range           */
  1182.   else if (m_ptr->cdis > MAX_SPELL_DIS)
  1183.     *took_turn    = FALSE;
  1184.   /* Must have unobstructed Line-Of-Sight       */
  1185.   else if (!los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
  1186.     *took_turn    = FALSE;
  1187.   else    /* Creature is going to cast a spell     */
  1188.     {
  1189.       *took_turn  = TRUE;
  1190.       /* Check to see if monster should be lit. */
  1191.       update_mon (monptr);
  1192.       /* Describe the attack                   */
  1193.       if (m_ptr->ml)
  1194.     (void) sprintf(cdesc, "The %s ", r_ptr->name);
  1195.       else
  1196.     (void) strcpy(cdesc, "It ");
  1197.       /* For "DIED_FROM" string     */
  1198. #ifdef ATARIST_MWC
  1199.       holder = CM_WIN;
  1200.       if (holder & r_ptr->cmove)
  1201. #else
  1202.       if (CM_WIN & r_ptr->cmove)
  1203. #endif
  1204.     (void) sprintf(ddesc, "The %s", r_ptr->name);
  1205.       else if (is_a_vowel (r_ptr->name[0]))
  1206.     (void) sprintf (ddesc, "an %s", r_ptr->name);
  1207.       else
  1208.     (void) sprintf(ddesc, "a %s", r_ptr->name);
  1209.       /* End DIED_FROM               */
  1210.  
  1211.       /* Extract all possible spells into spell_choice */
  1212. #ifdef ATARIST_MWC
  1213.       holder = ~CS_FREQ;
  1214.       i = (r_ptr->spells & holder);
  1215. #else
  1216.       i = (r_ptr->spells & ~CS_FREQ);
  1217. #endif
  1218.       k = 0;
  1219.       while (i != 0)
  1220.     {
  1221.       spell_choice[k] = bit_pos(&i);
  1222.       k++;
  1223.     }
  1224.       /* Choose a spell to cast                   */
  1225.       thrown_spell = spell_choice[randint(k) - 1];
  1226.       thrown_spell++;
  1227.       /* all except teleport_away() and drain mana spells always disturb */
  1228.       if (thrown_spell > 6 && thrown_spell != 17)
  1229.     disturb (1, 0);
  1230.       /* save some code/data space here, with a small time penalty */
  1231.       if ((thrown_spell < 14 && thrown_spell > 6) || (thrown_spell == 16))
  1232.     {
  1233.       (void) strcat(cdesc, "casts a spell.");
  1234.       msg_print(cdesc);
  1235.     }
  1236.       /* Cast the spell.                 */
  1237.       switch(thrown_spell)
  1238.     {
  1239.     case 5:     /*Teleport Short*/
  1240.       teleport_away(monptr, 5);
  1241.       break;
  1242.     case 6:     /*Teleport Long */
  1243.       teleport_away(monptr, MAX_SIGHT);
  1244.       break;
  1245.     case 7:     /*Teleport To     */
  1246.       teleport_to((int)m_ptr->fy, (int)m_ptr->fx);
  1247.       break;
  1248.     case 8:     /*Light Wound     */
  1249.       if (player_saves())
  1250.         msg_print("You resist the effects of the spell.");
  1251.       else
  1252.         take_hit(damroll(3, 8), ddesc);
  1253.       break;
  1254.     case 9:     /*Serious Wound */
  1255.       if (player_saves())
  1256.         msg_print("You resist the effects of the spell.");
  1257.       else
  1258.         take_hit(damroll(8, 8), ddesc);
  1259.       break;
  1260.     case 10:  /*Hold Person      */
  1261.       if (py.flags.free_act)
  1262.         msg_print("You are unaffected.");
  1263.       else if (player_saves())
  1264.         msg_print("You resist the effects of the spell.");
  1265.       else if (py.flags.paralysis > 0)
  1266.         py.flags.paralysis += 2;
  1267.       else
  1268.         py.flags.paralysis = randint(5)+4;
  1269.       break;
  1270.     case 11:  /*Cause Blindness*/
  1271.       if (player_saves())
  1272.         msg_print("You resist the effects of the spell.");
  1273.       else if (py.flags.blind > 0)
  1274.         py.flags.blind += 6;
  1275.       else
  1276.         py.flags.blind += 12 + randint(3);
  1277.       break;
  1278.     case 12:  /*Cause Confuse */
  1279.       if (player_saves())
  1280.         msg_print("You resist the effects of the spell.");
  1281.       else if (py.flags.confused > 0)
  1282.         py.flags.confused += 2;
  1283.       else
  1284.         py.flags.confused = randint(5) + 3;
  1285.       break;
  1286.     case 13:  /*Cause Fear      */
  1287.       if (player_saves())
  1288.         msg_print("You resist the effects of the spell.");
  1289.       else if (py.flags.afraid > 0)
  1290.         py.flags.afraid += 2;
  1291.       else
  1292.         py.flags.afraid = randint(5) + 3;
  1293.       break;
  1294.     case 14:  /*Summon Monster*/
  1295.       (void) strcat(cdesc, "magically summons a monster!");
  1296.       msg_print(cdesc);
  1297.       y = char_row;
  1298.       x = char_col;
  1299.       /* in case compact_monster() is called,it needs monptr */
  1300.       hack_monptr = monptr;
  1301.       (void) summon_monster(&y, &x, FALSE);
  1302.       hack_monptr = -1;
  1303.       update_mon ((int)cave[y][x].cptr);
  1304.       break;
  1305.     case 15:  /*Summon Undead*/
  1306.       (void) strcat(cdesc, "magically summons an undead!");
  1307.       msg_print(cdesc);
  1308.       y = char_row;
  1309.       x = char_col;
  1310.       /* in case compact_monster() is called,it needs monptr */
  1311.       hack_monptr = monptr;
  1312.       (void) summon_undead(&y, &x);
  1313.       hack_monptr = -1;
  1314.       update_mon ((int)cave[y][x].cptr);
  1315.       break;
  1316.     case 16:  /*Slow Person     */
  1317.       if (py.flags.free_act)
  1318.         msg_print("You are unaffected.");
  1319.       else if (player_saves())
  1320.         msg_print("You resist the effects of the spell.");
  1321.       else if (py.flags.slow > 0)
  1322.         py.flags.slow += 2;
  1323.       else
  1324.         py.flags.slow = randint(5) + 3;
  1325.       break;
  1326.     case 17:  /*Drain Mana     */
  1327.       if (py.misc.cmana > 0)
  1328.         {
  1329.           disturb (1, 0);
  1330.           (void) sprintf(outval, "%sdraws psychic energy from you!",cdesc);
  1331.           msg_print(outval);
  1332.           if (m_ptr->ml)
  1333.         {
  1334.           (void) sprintf(outval, "%sappears healthier.", cdesc);
  1335.           msg_print(outval);
  1336.         }
  1337.           r1 = (randint((int)r_ptr->level) >> 1) + 1;
  1338.           if (r1 > py.misc.cmana)
  1339.         {
  1340.           r1 = py.misc.cmana;
  1341.           py.misc.cmana = 0;
  1342.           py.misc.cmana_frac = 0;
  1343.         }
  1344.           else
  1345.         py.misc.cmana -= r1;
  1346.           prt_cmana();
  1347.           m_ptr->hp += 6*(r1);
  1348.         }
  1349.       break;
  1350.     case 20:  /*Breath Light */
  1351.       (void) strcat(cdesc, "breathes lightning.");
  1352.       msg_print(cdesc);
  1353.       breath(GF_LIGHTNING, char_row, char_col, (m_ptr->hp / 4), ddesc,
  1354.          monptr);
  1355.       break;
  1356.     case 21:  /*Breath Gas     */
  1357.       (void) strcat(cdesc, "breathes gas.");
  1358.       msg_print(cdesc);
  1359.       breath(GF_POISON_GAS, char_row, char_col, (m_ptr->hp / 3), ddesc,
  1360.          monptr);
  1361.       break;
  1362.     case 22:  /*Breath Acid     */
  1363.       (void) strcat(cdesc, "breathes acid.");
  1364.       msg_print(cdesc);
  1365.       breath(GF_ACID, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr);
  1366.       break;
  1367.     case 23:  /*Breath Frost */
  1368.       (void) strcat(cdesc, "breathes frost.");
  1369.       msg_print(cdesc);
  1370.       breath(GF_FROST, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr);
  1371.       break;
  1372.     case 24:  /*Breath Fire     */
  1373.       (void) strcat(cdesc, "breathes fire.");
  1374.       msg_print(cdesc);
  1375.       breath(GF_FIRE, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr);
  1376.       break;
  1377.     default:
  1378.       (void) strcat (cdesc, "cast unknown spell.");
  1379.       msg_print(cdesc);
  1380.     }
  1381.       /* End of spells                       */
  1382.       if (m_ptr->ml)
  1383.     {
  1384.       c_recall[m_ptr->mptr].r_spells |= 1L << (thrown_spell-1);
  1385.       if ((c_recall[m_ptr->mptr].r_spells & CS_FREQ) != CS_FREQ)
  1386.         c_recall[m_ptr->mptr].r_spells++;
  1387.       if (death && c_recall[m_ptr->mptr].r_deaths < MAX_SHORT)
  1388.         c_recall[m_ptr->mptr].r_deaths++;
  1389.     }
  1390.     }
  1391. }
  1392.  
  1393.  
  1394. /* Places creature adjacent to given location        -RAK-    */
  1395. /* Rats and Flys are fun!                     */
  1396. int multiply_monster(y, x, cr_index, monptr)
  1397. int y, x, cr_index;
  1398. int monptr;
  1399. {
  1400.   register int i, j, k;
  1401.   register cave_type *c_ptr;
  1402.   int result;
  1403. #ifdef ATARIST_MWC
  1404.   int32u holder;
  1405. #endif
  1406.  
  1407.   i = 0;
  1408.   do
  1409.     {
  1410.       j = y - 2 + randint(3);
  1411.       k = x - 2 + randint(3);
  1412.       /* don't create a new creature on top of the old one, that causes
  1413.      invincible/invisible creatures to appear */
  1414.       if (in_bounds(j, k) && (j != y || k != x))
  1415.     {
  1416.       c_ptr = &cave[j][k];
  1417.       if ((c_ptr->fval <= MAX_OPEN_SPACE) && (c_ptr->tptr == 0) &&
  1418.           (c_ptr->cptr != 1))
  1419.         {
  1420.           if (c_ptr->cptr > 1)     /* Creature there already?    */
  1421.         {
  1422.           /* Some critters are cannibalistic!        */
  1423. #ifdef ATARIST_MWC
  1424.           holder = CM_EATS_OTHER;
  1425.           if ((c_list[cr_index].cmove & holder)
  1426. #else
  1427.           if ((c_list[cr_index].cmove & CM_EATS_OTHER)
  1428. #endif
  1429.               /* Check the experience level -CJS- */
  1430.              && c_list[cr_index].mexp >=
  1431.               c_list[m_list[c_ptr->cptr].mptr].mexp)
  1432.             {
  1433.               /* It ate an already processed monster.Handle normally.*/
  1434.               if (monptr < c_ptr->cptr)
  1435.             delete_monster((int) c_ptr->cptr);
  1436.               /* If it eats this monster, an already processed mosnter
  1437.              will take its place, causing all kinds of havoc.
  1438.              Delay the kill a bit. */
  1439.               else
  1440.             fix1_delete_monster((int) c_ptr->cptr);
  1441.  
  1442.               /* in case compact_monster() is called,it needs monptr */
  1443.               hack_monptr = monptr;
  1444.               /* Place_monster() may fail if monster list full.  */
  1445.               result = place_monster(j, k, cr_index, FALSE);
  1446.               hack_monptr = -1;
  1447.               if (! result)
  1448.             return FALSE;
  1449.               mon_tot_mult++;
  1450.               return check_mon_lite(j, k);
  1451.             }
  1452.         }
  1453.           else
  1454.         /* All clear,  place a monster      */
  1455.         {
  1456.           /* in case compact_monster() is called,it needs monptr */
  1457.           hack_monptr = monptr;
  1458.           /* Place_monster() may fail if monster list full.  */
  1459.           result = place_monster(j, k, cr_index, FALSE);
  1460.           hack_monptr = -1;
  1461.           if (! result)
  1462.             return FALSE;
  1463.           mon_tot_mult++;
  1464.           return check_mon_lite(j, k);
  1465.         }
  1466.         }
  1467.     }
  1468.       i++;
  1469.     }
  1470.   while (i <= 18);
  1471.   return FALSE;
  1472. }
  1473.  
  1474.  
  1475. /* Move the critters about the dungeon            -RAK-    */
  1476. static void mon_move(monptr, rcmove)
  1477. int monptr;
  1478. int32u *rcmove;
  1479. {
  1480.   register int i, j;
  1481.   int k, move_test, dir;
  1482. #ifdef M_XENIX
  1483.   /* Avoid 'register' bug.  */
  1484.   creature_type *r_ptr;
  1485. #else
  1486.   register creature_type *r_ptr;
  1487. #endif
  1488.   register monster_type *m_ptr;
  1489.   int mm[9];
  1490. #ifdef ATARIST_MWC
  1491.   int32u holder;
  1492. #endif
  1493.   int rest_val;
  1494.  
  1495.   m_ptr = &m_list[monptr];
  1496.   r_ptr = &c_list[m_ptr->mptr];
  1497.   /* Does the critter multiply?                   */
  1498.   /* rest could be negative, to be safe, only use mod with positive values. */
  1499.   rest_val = abs (py.flags.rest);
  1500. #ifdef ATARIST_MWC
  1501.   holder = CM_MULTIPLY;
  1502.   if ((r_ptr->cmove & holder) && (MAX_MON_MULT >= mon_tot_mult) &&
  1503. #else
  1504.   if ((r_ptr->cmove & CM_MULTIPLY) && (MAX_MON_MULT >= mon_tot_mult) &&
  1505. #endif
  1506.       ((rest_val % MON_MULT_ADJ) == 0))
  1507.     {
  1508.       k = 0;
  1509.       for (i = m_ptr->fy-1; i <= m_ptr->fy+1; i++)
  1510.     for (j = m_ptr->fx-1; j <= m_ptr->fx+1; j++)
  1511.       if (in_bounds(i, j) && (cave[i][j].cptr > 1))
  1512.         k++;
  1513.       /* can't call randint with a value of zero, increment counter
  1514.      to allow creature multiplication */
  1515.       if (k == 0)
  1516.     k++;
  1517.       if ((k < 4) && (randint(k*MON_MULT_ADJ) == 1))
  1518.     if (multiply_monster((int)m_ptr->fy, (int)m_ptr->fx,
  1519.              (int)m_ptr->mptr, monptr))
  1520. #ifdef ATARIST_MWC
  1521.       *rcmove |= holder;
  1522. #else
  1523.       *rcmove |= CM_MULTIPLY;
  1524. #endif
  1525.     }
  1526.   move_test = FALSE;
  1527.  
  1528.   /* if in wall, must immediately escape to a clear area */
  1529. #ifdef ATARIST_MWC
  1530.   holder = CM_PHASE;
  1531.   if (!(r_ptr->cmove & holder) &&
  1532. #else
  1533.   if (!(r_ptr->cmove & CM_PHASE) &&
  1534. #endif
  1535.       (cave[m_ptr->fy][m_ptr->fx].fval >= MIN_CAVE_WALL))
  1536.     {
  1537.       /* If the monster is already dead, don't kill it again!
  1538.      This can happen for monsters moving faster than the player.  They
  1539.      will get multiple moves, but should not if they die on the first
  1540.      move.  This is only a problem for monsters stuck in rock.  */
  1541.       if (m_ptr->hp < 0)
  1542.     return;
  1543.  
  1544.       k = 0;
  1545.       dir = 1;
  1546.       /* note direction of for loops matches direction of keypad from 1 to 9*/
  1547.       /* do not allow attack against the player */
  1548.       /* Must cast fy-1 to signed int, so that a nagative value of i will
  1549.      fail the comparison.  */
  1550.       for (i = m_ptr->fy+1; i >= (int)(m_ptr->fy-1); i--)
  1551.     for (j = m_ptr->fx-1; j <= m_ptr->fx+1; j++)
  1552.       {
  1553.         if ((dir != 5) && (cave[i][j].fval <= MAX_OPEN_SPACE)
  1554.         && (cave[i][j].cptr != 1))
  1555.           mm[k++] = dir;
  1556.         dir++;
  1557.       }
  1558.       if (k != 0)
  1559.     {
  1560.       /* put a random direction first */
  1561.       dir = randint (k) - 1;
  1562.       i = mm[0];
  1563.       mm[0] = mm[dir];
  1564.       mm[dir] = i;
  1565.       make_move (monptr, mm, rcmove);
  1566.       /* this can only fail if mm[0] has a rune of protection */
  1567.     }
  1568.       /* if still in a wall, let it dig itself out, but also apply some
  1569.      more damage */
  1570.       if (cave[m_ptr->fy][m_ptr->fx].fval >= MIN_CAVE_WALL)
  1571.     {
  1572.       /* in case the monster dies, may need to call fix1_delete_monster()
  1573.          instead of delete_monsters() */
  1574.       hack_monptr = monptr;
  1575.       i = mon_take_hit(monptr, damroll (8, 8));
  1576.       hack_monptr = -1;
  1577.       if (i >= 0)
  1578.         {
  1579.           msg_print("You hear a scream muffled by rock!");
  1580.           prt_experience();
  1581.         }
  1582.       else
  1583.         {
  1584.           msg_print ("A creature digs itself out from the rock!");
  1585.           (void) twall ((int)m_ptr->fy, (int)m_ptr->fx, 1, 0);
  1586.         }
  1587.     }
  1588.       return;  /* monster movement finished */
  1589.     }
  1590.   /* Creature is confused?  Chance it becomes un-confused  */
  1591.   else if (m_ptr->confused)
  1592.     {
  1593.       mm[0] = randint(9);
  1594.       mm[1] = randint(9);
  1595.       mm[2] = randint(9);
  1596.       mm[3] = randint(9);
  1597.       mm[4] = randint(9);
  1598.       /* don't move him if he is not supposed to move! */
  1599.       if (!(r_ptr->cmove & CM_ATTACK_ONLY))
  1600.     make_move(monptr, mm, rcmove);
  1601.       if (randint(8) == 1)
  1602.     m_ptr->confused = FALSE;
  1603.       move_test = TRUE;
  1604.     }
  1605.   /* Creature may cast a spell */
  1606.   else if (r_ptr->spells != 0)
  1607.     mon_cast_spell(monptr, &move_test);
  1608.   if (!move_test)
  1609.     {
  1610.       /* 75% random movement */
  1611.       if ((r_ptr->cmove & CM_75_RANDOM) && (randint(100) < 75))
  1612.     {
  1613.       mm[0] = randint(9);
  1614.       mm[1] = randint(9);
  1615.       mm[2] = randint(9);
  1616.       mm[3] = randint(9);
  1617.       mm[4] = randint(9);
  1618.       *rcmove |= CM_75_RANDOM;
  1619.       make_move(monptr, mm, rcmove);
  1620.     }
  1621.       /* 40% random movement */
  1622.       else if ((r_ptr->cmove & CM_40_RANDOM) && (randint(100) < 40))
  1623.     {
  1624.       mm[0] = randint(9);
  1625.       mm[1] = randint(9);
  1626.       mm[2] = randint(9);
  1627.       mm[3] = randint(9);
  1628.       mm[4] = randint(9);
  1629.       *rcmove |= CM_40_RANDOM;
  1630.       make_move(monptr, mm, rcmove);
  1631.     }
  1632.       /* 20% random movement */
  1633.       else if ((r_ptr->cmove & CM_20_RANDOM) && (randint(100) < 20))
  1634.     {
  1635.       mm[0] = randint(9);
  1636.       mm[1] = randint(9);
  1637.       mm[2] = randint(9);
  1638.       mm[3] = randint(9);
  1639.       mm[4] = randint(9);
  1640.       *rcmove |= CM_20_RANDOM;
  1641.       make_move(monptr, mm, rcmove);
  1642.     }
  1643.       /* Normal movement */
  1644.       else if (r_ptr->cmove & CM_MOVE_NORMAL)
  1645.     {
  1646.       if (randint(200) == 1)
  1647.         {
  1648.           mm[0] = randint(9);
  1649.           mm[1] = randint(9);
  1650.           mm[2] = randint(9);
  1651.           mm[3] = randint(9);
  1652.           mm[4] = randint(9);
  1653.         }
  1654.       else
  1655.         get_moves(monptr, mm);
  1656.       *rcmove |= CM_MOVE_NORMAL;
  1657.       make_move(monptr, mm, rcmove);
  1658.     }
  1659.       /* Attack, but don't move */
  1660.       else if (r_ptr->cmove & CM_ATTACK_ONLY)
  1661.     {
  1662.       if (m_ptr->cdis < 2)
  1663.         {
  1664.           get_moves(monptr, mm);
  1665.           make_move(monptr, mm, rcmove);
  1666.         }
  1667.       else
  1668.         /* Learn that the monster does does not move when it should have
  1669.            moved, but didn't.  */
  1670.         *rcmove |= CM_ATTACK_ONLY;
  1671.     }
  1672.       else if ((r_ptr->cmove & CM_ONLY_MAGIC) && (m_ptr->cdis < 2))
  1673.     {
  1674.       /* A little hack for Quylthulgs, so that one will eventually notice
  1675.          that they have no physical attacks.  */
  1676.       if (c_recall[m_ptr->mptr].r_attacks[0] < MAX_UCHAR)
  1677.         c_recall[m_ptr->mptr].r_attacks[0]++;
  1678.       /* Another little hack for Quylthulgs, so that one can eventually
  1679.          learn their speed.  */
  1680.       if (c_recall[m_ptr->mptr].r_attacks[0] > 20)
  1681.         c_recall[m_ptr->mptr].r_cmove |= CM_ONLY_MAGIC;
  1682.     }
  1683.     }
  1684. }
  1685.  
  1686.  
  1687. /* Creatures movement and attacking are done from here    -RAK-    */
  1688. void creatures(attack)
  1689. int attack;
  1690. {
  1691.   register int i, k;
  1692.   register monster_type *m_ptr;
  1693.   recall_type *r_ptr;
  1694.   int32u notice, rcmove;
  1695.   int wake, ignore;
  1696.   vtype cdesc;
  1697. #ifdef ATARIST_MWC
  1698.   int32u holder;
  1699. #endif
  1700.  
  1701.   /* Process the monsters  */
  1702.   for (i = mfptr - 1; i >= MIN_MONIX && !death; i--)
  1703.     {
  1704.       m_ptr = &m_list[i];
  1705.       /* Get rid of an eaten/breathed on monster.  Note: Be sure not to
  1706.      process this monster. This is necessary because we can't delete
  1707.      monsters while scanning the m_list here. */
  1708.       if (m_ptr->hp < 0)
  1709.     {
  1710.       fix2_delete_monster(i);
  1711.       continue;
  1712.     }
  1713.  
  1714.       m_ptr->cdis = distance(char_row, char_col,
  1715.                  (int)m_ptr->fy, (int)m_ptr->fx);
  1716.       if (attack)   /* Attack is argument passed to CREATURE*/
  1717.     {
  1718.       k = movement_rate(m_ptr->cspeed);
  1719.       if (k <= 0)
  1720.         update_mon(i);
  1721.       else
  1722.         while (k > 0)
  1723.           {
  1724.         k--;
  1725.         wake = FALSE;
  1726.         ignore = FALSE;
  1727.         rcmove = 0;
  1728.         if (m_ptr->ml || (m_ptr->cdis <= c_list[m_ptr->mptr].aaf)
  1729.             /* Monsters trapped in rock must be given a turn also,
  1730.                so that they will die/dig out immediately.  */
  1731. #ifdef ATARIST_MWC
  1732.             || ((! (c_list[m_ptr->mptr].cmove & (holder = CM_PHASE)))
  1733. #else
  1734.             || ((! (c_list[m_ptr->mptr].cmove & CM_PHASE))
  1735. #endif
  1736.             && cave[m_ptr->fy][m_ptr->fx].fval >= MIN_CAVE_WALL))
  1737.           {
  1738.             if (m_ptr->csleep > 0)
  1739.               if (py.flags.aggravate)
  1740.             m_ptr->csleep = 0;
  1741.               else if ((py.flags.rest == 0 && py.flags.paralysis < 1)
  1742.                    || (randint(50) == 1))
  1743.             {
  1744.               notice = randint(1024);
  1745.               if (notice*notice*notice <= (1L << (29 - py.misc.stl)))
  1746.                 {
  1747.                   m_ptr->csleep -= (100 / m_ptr->cdis);
  1748.                   if (m_ptr->csleep > 0)
  1749.                 ignore = TRUE;
  1750.                   else
  1751.                 {
  1752.                   wake = TRUE;
  1753.                   /* force it to be exactly zero */
  1754.                   m_ptr->csleep = 0;
  1755.                 }
  1756.                 }
  1757.             }
  1758.             if (m_ptr->stunned != 0)
  1759.               {
  1760.             /* NOTE: Balrog = 100*100 = 10000, it always
  1761.                recovers instantly */
  1762.             if (randint(5000) < c_list[m_ptr->mptr].level
  1763.                 * c_list[m_ptr->mptr].level)
  1764.               m_ptr->stunned = 0;
  1765.             else
  1766.               m_ptr->stunned--;
  1767.             if (m_ptr->stunned == 0)
  1768.               {
  1769.                 if (!m_ptr->ml)
  1770.                   (void) strcpy(cdesc, "It ");
  1771.                 else
  1772.                   (void) sprintf(cdesc, "The %s ",
  1773.                          c_list[m_ptr->mptr].name);
  1774.                 msg_print(strcat(cdesc,
  1775.                          "recovers and glares at you."));
  1776.               }
  1777.               }
  1778.             if ((m_ptr->csleep == 0) && (m_ptr->stunned == 0))
  1779.               mon_move (i, &rcmove);
  1780.           }
  1781.  
  1782.         update_mon(i);
  1783.         if (m_ptr->ml)
  1784.           {
  1785.             r_ptr = &c_recall[m_ptr->mptr];
  1786.             if (wake)
  1787.               {
  1788.             if (r_ptr->r_wake < MAX_UCHAR)
  1789.               r_ptr->r_wake++;
  1790.               }
  1791.             else if (ignore)
  1792.               {
  1793.             if (r_ptr->r_ignore < MAX_UCHAR)
  1794.               r_ptr->r_ignore++;
  1795.               }
  1796.             r_ptr->r_cmove |= rcmove;
  1797.           }
  1798.           }
  1799.     }
  1800.       else
  1801.     update_mon(i);
  1802.  
  1803.       /* Get rid of an eaten/breathed on monster.  This is necessary because
  1804.      we can't delete monsters while scanning the m_list here.  This
  1805.      monster may have been killed during mon_move(). */
  1806.       if (m_ptr->hp < 0)
  1807.     {
  1808.       fix2_delete_monster(i);
  1809.       continue;
  1810.     }
  1811.     }
  1812.   /* End processing monsters       */
  1813. }
  1814.